<template>
	<view v-if="visibleSync" class="pos-f pos-full overflow-hidden use-popup"
		:class="{ 'use-popup-visible': popupShow }" :style="[customStyle]">
		<use-mask :show="popupShow && mask" :maskClickAble="maskCloseAble" @click="maskClick"></use-mask>
		<view class="pos-a use-popup-content" :class="[
				bgclass,
				safeAreaInsetBottom ? 'safe-area-inset-bottom' : '',
				'use-popup-' + mode,
				popupShow ? 'use-popup-content-visible' : 'use-popup-content-hidden',
				zoom && mode == 'center' ? 'use-animation-zoom' : ''
			]" :style="[style]" @tap.stop.prevent @touchmove.stop.prevent @tap="modeCenterClose(mode)">
			<view v-if="mode == 'center'" class="bg-popup pos-r use-mode-center-box border-radius" 
				:style="[centerStyle]" @tap.stop.prevent @touchmove.stop.prevent>
				<slot />
			</view>
			<block v-else>
				<slot />
			</block>

			<view v-if="closeIcon" class="pos-a pos-top pos-right padding-sm fs-xl" @click="close">
				<view class="iconfont icon-guanbi"></view>
			</view>
		</view>
	</view>
</template>

<script setup>
	import utils from '@/utils/util.js'
	import {
		ref,
		watch,
		inject,
		provide,
		computed,
		defineEmits,
		getCurrentInstance,
		onMounted
	} from 'vue'
	const {
		ctx
	} = getCurrentInstance();
	//console.log("ctx", ctx);
	const props = defineProps({
		/**
		 * 显示状态
		 */
		show: Boolean,
		/**
		 * 弹出方向，left|right|top|bottom|center
		 */
		mode: {
			type: String,
			default: 'left'
		},
		/**
		 * 是否显示遮罩
		 */
		mask: {
			type: Boolean,
			default: true
		},
		/**
		 * 背景 class 样式
		 * */
		bgclass: {
			type: String,
			default: 'bg-popup'
		},
		width: {
			type: String,
			default: '75%'
		},
		// 抽屉的宽度(mode=left|right)，或者高度(mode=top|bottom)，单位rpx，或者"auto"
		// 或者百分比"50%"，表示由内容撑开高度或者宽度
		length: {
			type: [Number, String],
			default: 'auto'
		},
		// 是否开启缩放动画，只在mode=center时有效
		zoom: {
			type: Boolean,
			default: true
		},
		// 是否开启底部安全区适配，开启的话，会在iPhoneX机型底部添加一定的内边距
		safeAreaInsetBottom: {
			type: Boolean,
			default: false
		},
		// 是否可以通过点击遮罩进行关闭
		maskCloseAble: {
			type: Boolean,
			default: true
		},
		// 用户自定义样式
		customStyle: {
			type: Object,
			default () {
				return {};
			}
		},
		value: Boolean,
		// 此为内部参数，不在文档对外使用，为了解决Picker和keyboard等融合了弹窗的组件
		// 对v-model双向绑定多层调用造成报错不能修改props值的问题
		popup: {
			type: Boolean,
			default: true
		},
		// 显示显示弹窗的圆角，单位rpx
		borderRadius: {
			type: [Number, String],
			default: 0
		},
		zIndex: {
			type: [Number, String],
			default: '95'
		},
		closeIcon: {
			type: Boolean,
			default: false
		},
		date: String
	})
	
	// 2、定义发射给父组件的方法
	const emits = defineEmits(['open', 'close'])

	const visibleSync = ref(false)
	const popupShow = ref(false)
	const userLocation = inject('location', 'The Universe')
	watch(
		() => props.show,
		() => {
			console.log("data:数据变更过",props.show);
			if (props.show) {
				open()
			} else {
				close()
			}
		}, {
			onTrack(e) {
				//console.log(e);
			},
			onTrigger(e) {
				//console.log(e);
			}
		}
	);

	// 一个计算属性 ref
	const style = computed(() => {
		let style = {};
		let translate = '100%';
		// 判断是否是否百分比或者auto值，是的话，直接使用该值，否则默认为rpx单位的数值
		let length = (/%$/.test(props.length) || props.length == 'auto') ? props.length : uni.upx2px(props
			.length) +
			'px';
		// 如果是左边或者上边弹出时，需要给translate设置为负值，用于隐藏
		if (props.mode == 'left' || props.mode == 'top') {
			translate = length == 'auto' ? '-100%' : '-' + length;
		}
		if (props.mode == 'left' || props.mode == 'right') {
			style = {
				width: length,
				height: '100%',
				transform: `translate3D(${translate},0px,0px)`
			};
		} else if (props.mode == 'top' || props.mode == 'bottom') {
			style = {
				width: '100%',
				height: length,
				transform: `translate3D(0px,${translate},0px)`
			};
		}
		style.zIndex = props.zIndex;

		// 如果用户设置了borderRadius值，添加弹窗的圆角
		if (props.borderRadius) {
			switch (props.mode) {
				case 'top':
					style.borderRadius = `0 0 ${props.borderRadius}rpx ${props.borderRadius}rpx`;
					break;
				case 'right':
					style.borderRadius = `${props.borderRadius}rpx 0 0 ${props.borderRadius}rpx`;
					break;
				case 'bottom':
					style.borderRadius = `${props.borderRadius}rpx ${props.borderRadius}rpx 0 0`;
					break;
				case 'left':
					style.borderRadius = `0 ${props.borderRadius}rpx ${props.borderRadius}rpx 0`;
					break;
				default:
					break;
			}
			// 不加可能圆角无效
			style.overflow = 'hidden';
		}
		console.log(style)
		return style;
	})


	const centerStyle = computed(() => {
		let style = {};
		let length = (/%$/.test(props.length) || props.length == 'auto') ? props.length : uni.upx2px(props
			.length) +
			'px';
		console.log(length)
		style.width = length;
		style.width = props.width||"75%"
		style.zIndex = props.zIndex;
		if (props.borderRadius) {
			style.borderRadius = `${props.borderRadius}rpx`;
			// 不加可能圆角无效
			style.overflow = 'hidden';
		}
		return style;
	})
	onMounted(() => {
		visibleSync.value = props.show;
		utils.timerout(() => {
			popupShow.value = props.show;
		}, 30);
	})
	const open = () => {
		//console.log("打开")
		change('visibleSync', 'popupShow', true);
	}
	const close = () => {
		//console.log('关闭')
		if (popupShow.value) {
			change('popupShow', 'visibleSync', false);
			return true;
		}

		return false;
	}
	// 遮罩被点击
	const maskClick = () => {
		close();
	}
	// 中部弹出时，需要.use-popup-content将居中内容，此元素会铺满屏幕，点击需要关闭弹窗
	// 让其只在mode=center时起作用
	const modeCenterClose = (mode) => {
		if (mode != 'center' || !props.maskCloseAble) return;
		close();
	}
	// 此处的原理是，关闭时先通过动画隐藏弹窗和遮罩，再移除整个组件
	// 打开时，先渲染组件，延时一定时间再让遮罩和弹窗的动画起作用
	const change = (param1, param2, state) => {
		if (props.value.show) emits('input', state);
		popupShow.value = state;
		utils.timerout(() => {
			visibleSync.value = state;
			emits(state ? 'open' : 'close');
		}, state ? 30 : 250);
	}
</script>

<style lang="scss">
	.use-popup {
		z-index: 99;
	}

	.use-popup-content {
		z-index:92;
		transition: all 0.25s ease-in-out;
	}

	.use-popup-content-hidden {
		transition: all 0.125s ease-in-out;
	}

	.use-popup-top {
		top: 0;
		right: 0;
		left: 0;
	}

	.use-popup-right {
		top: 0;
		right: 0;
		bottom: 0;
	}

	.use-popup-bottom {
		right: 0;
		bottom: 0;
		left: 0;
	}

	.use-popup-left {
		top: 0;
		bottom: 0;
		left: 0;
	}

	.use-popup-center {
		display: flex;
		align-items: center;
		justify-content: center;
		flex-direction: column;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		opacity: 0;
		z-index: 92;
	}

	.use-mode-center-box {
		min-width: 100rpx;
		min-height: 100rpx;
	}

	.use-popup-content-visible.use-popup-center {
		transform: scale(1);
		opacity: 1;
	}

	.use-animation-zoom {
		transform: scale(1.15);
	}

	.use-popup-content-visible {
		transform: translate3D(0px, 0px, 0px) !important;
	}
</style>